package com.hong.spring.config.diamond;


import com.taobao.diamond.manager.DiamondManager;
import com.taobao.diamond.manager.ManagerListener;
import com.taobao.diamond.manager.impl.DefaultDiamondManager;
import org.apache.commons.configuration.ConfigurationRuntimeException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.util.StringUtils;

import javax.naming.ConfigurationException;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.concurrent.Executor;

/**
 * 功能描述: 动态拉取diamond!
 *
 * @param:
 * @return:
 * @auther: csh
 * @date: 2020/11/9 11:34
 */
@Configuration
public class ApplicationConfigurer {

    private static final Logger logger = LoggerFactory.getLogger(ApplicationConfigurer.class);

    //diamond系统配置的dataId
    String dataId = "hong";

    @Bean
    public PropertySourcesPlaceholderConfigurer createPropertySourcesPlaceholderConfigurer() throws ConfigurationException, IOException {
        PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();

        //加载diamond配置信息
        loadDiamondConfig();

        if (!StringUtils.isEmpty(dataId)) {
            String[] dataIds = dataId.split(",");
            for (int i = 0; i < dataIds.length; i++) {
                //diamond客户端调用服务端获取配置信息
                DiamondManager manager = new DefaultDiamondManager(dataIds[i], new ManagerListener() {
                    @Override
                    public Executor getExecutor() {
                        return null;
                    }

                    @Override
                    public void receiveConfigInfo(String configInfo) {
                        //配置信息动态修改将触发此方法
                        System.out.println("receive config: " + configInfo);
                        propertyPlaceholderConfigurer.setProperties(getProperties(new StringReader(configInfo)));
                    }
                });
                /**
                 * 同步获取一份有效的配置信息，按照本地文件->diamond服务器->上一次正确配置的snapshot
                 * 的优先顺序获取， 如果这些途径都无效，则返回null
                 *
                 * @param timeout
                 *            从网络获取配置信息的超时，单位毫秒
                 * @return 配置信息
                 */
                String configInfo = manager.getAvailableConfigureInfomation(1000);
                System.out.println("获取的内容:" + configInfo);
                //关闭
                //manager.close();
                //解析Propertie配置信息
                propertyPlaceholderConfigurer.setProperties(getProperties(new StringReader(configInfo)));
            }
        }
        return propertyPlaceholderConfigurer;
    }


    /**
     * 功能描述: 获取所有属性
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/11/9 11:34
     */
    private Properties getProperties(StringReader in) {
        Map <String, String> map = getPropertisMap(in);
        Properties properties = new Properties();
        for (String key : map.keySet()) {
            properties.setProperty(key, map.get(key));
        }
        return properties;
    }

    /**
     * 功能描述: 解析文件内容
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/11/9 11:35
     */
    private Map getPropertisMap(StringReader in) {
        Map <String, String> map = new HashMap <String, String>();
        PropertiesConfiguration.PropertiesReader reader = new PropertiesConfiguration.PropertiesReader(in);
        try {
            while (reader.nextProperty()) {
                String key = reader.getPropertyName();
                String value = reader.getPropertyValue();
                map.put(key, value);
            }
        } catch (IOException ioex) {
            throw new ConfigurationRuntimeException(ioex);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                logger.error("load config exception", e);
            } finally {
                return map;
            }
        }
    }

    /**
     * 功能描述: 加载配置信息
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/11/9 11:35
     */
    private void loadDiamondConfig() {
        URL url = this.getClass().getClassLoader().getResource("diamond.properties");
        if (url != null) {
            File file = new File(url.getFile());
            Properties prop = new Properties();
            try {
                prop.load(new FileInputStream(file));
                dataId = prop.getProperty("diamond.dataId");
            } catch (IOException e) {
            }
        }
    }
}